home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Python 1.4 / Python 1.4 source / Modules / flmodule.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-28  |  49.9 KB  |  2,543 lines  |  [TEXT/CWIE]

  1. /**********************************************************
  2. Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
  3. The Netherlands.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its
  8. documentation for any purpose and without fee is hereby granted,
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in
  11. supporting documentation, and that the names of Stichting Mathematisch
  12. Centrum or CWI or Corporation for National Research Initiatives or
  13. CNRI not be used in advertising or publicity pertaining to
  14. distribution of the software without specific, written prior
  15. permission.
  16.  
  17. While CWI is the initial source for this software, a modified version
  18. is made available by the Corporation for National Research Initiatives
  19. (CNRI) at the Internet address ftp://ftp.python.org.
  20.  
  21. STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
  22. REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
  23. MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
  24. CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
  25. DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  26. PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  27. TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  28. PERFORMANCE OF THIS SOFTWARE.
  29.  
  30. ******************************************************************/
  31.  
  32. /* FL module -- interface to Mark Overmars' FORMS Library. */
  33.  
  34. /* This code works with FORMS version 2.2a.
  35.    FORMS can be ftp'ed from ftp.cs.ruu.nl (131.211.80.17), directory
  36.    /pub/SGI/FORMS. */
  37.  
  38. /* A half-hearted attempt has been made to allow programs using this
  39.  * module to exploit parallelism (through the threads module). No provisions
  40.  * have been made for multiple threads to use this module at the same time,
  41.  * though. So, a program with a forms thread and a non-forms thread will work
  42.  * fine but a program with two threads using forms will probably crash (unless
  43.  * the program takes precaution to ensure that only one thread can be in
  44.  * this module at any time). This will have to be fixed some time.
  45.  * (A fix will probably also have to synchronise with the gl module).
  46.  */
  47.  
  48. #include "forms.h"
  49.  
  50. #include "allobjects.h"
  51. #include "import.h"
  52. #include "modsupport.h"
  53. #include "structmember.h"
  54. #include "ceval.h"
  55.  
  56. /* Generic Forms Objects */
  57.  
  58. typedef struct {
  59.     OB_HEAD
  60.     FL_OBJECT *ob_generic;
  61.     struct methodlist *ob_methods;
  62.     object *ob_callback;
  63.     object *ob_callback_arg;
  64. } genericobject;
  65.  
  66. staticforward typeobject GenericObjecttype;
  67.  
  68. #define is_genericobject(g) ((g)->ob_type == &GenericObjecttype)
  69.  
  70. /* List of all objects (XXX this should be a hash table on address...) */
  71.  
  72. static object *allgenerics = NULL;
  73. static int nfreeslots = 0;
  74.  
  75. /* Add an object to the list of known objects */
  76.  
  77. static void
  78. knowgeneric(g)
  79.     genericobject *g;
  80. {
  81.     int i, n;
  82.     /* Create the list if it doesn't already exist */
  83.     if (allgenerics == NULL) {
  84.         allgenerics = newlistobject(0);
  85.         if (allgenerics == NULL) {
  86.             err_clear();
  87.             return; /* Too bad, live without allgenerics... */
  88.         }
  89.     }
  90.     if (nfreeslots > 0) {
  91.         /* Search the list for reusable slots (NULL items) */
  92.         /* XXX This can be made faster! */
  93.         n = getlistsize(allgenerics);
  94.         for (i = 0; i < n; i++) {
  95.             if (getlistitem(allgenerics, i) == NULL) {
  96.                 INCREF(g);
  97.                 setlistitem(allgenerics, i, (object *)g);
  98.                 nfreeslots--;
  99.                 return;
  100.             }
  101.         }
  102.         /* Strange... no free slots found... */
  103.         nfreeslots = 0;
  104.     }
  105.     /* No free entries, append new item to the end */
  106.     addlistitem(allgenerics, (object *)g);
  107. }
  108.  
  109. /* Find an object in the list of known objects */
  110.  
  111. static genericobject *
  112. findgeneric(generic)
  113.     FL_OBJECT *generic;
  114. {
  115.     int i, n;
  116.     genericobject *g;
  117.     
  118.     if (allgenerics == NULL)
  119.         return NULL; /* No objects known yet */
  120.     n = getlistsize(allgenerics);
  121.     for (i = 0; i < n; i++) {
  122.         g = (genericobject *)getlistitem(allgenerics, i);
  123.         if (g != NULL && g->ob_generic == generic)
  124.             return g;
  125.     }
  126.     return NULL; /* Unknown object */
  127. }
  128.  
  129. /* Remove an object from the list of known objects */
  130.  
  131. static void
  132. forgetgeneric(g)
  133.     genericobject *g;
  134. {
  135.     int i, n;
  136.     
  137.     XDECREF(g->ob_callback);
  138.     g->ob_callback = NULL;
  139.     XDECREF(g->ob_callback_arg);
  140.     g->ob_callback_arg = NULL;
  141.     if (allgenerics == NULL)
  142.         return; /* No objects known yet */
  143.     n = getlistsize(allgenerics);
  144.     for (i = 0; i < n; i++) {
  145.         if (g == (genericobject *)getlistitem(allgenerics, i)) {
  146.             setlistitem(allgenerics, i, (object *)NULL);
  147.             nfreeslots++;
  148.             break;
  149.         }
  150.     }
  151. }
  152.  
  153. /* Called when a form is about to be freed --
  154.    remove all the objects that we know about from it. */
  155.  
  156. static void
  157. releaseobjects(form)
  158.     FL_FORM *form;
  159. {
  160.     int i, n;
  161.     genericobject *g;
  162.     
  163.     if (allgenerics == NULL)
  164.         return; /* No objects known yet */
  165.     n = getlistsize(allgenerics);
  166.     for (i = 0; i < n; i++) {
  167.         g = (genericobject *)getlistitem(allgenerics, i);
  168.         if (g != NULL && g->ob_generic->form == form) {
  169.             fl_delete_object(g->ob_generic);
  170.             /* The object is now unreachable for
  171.                do_forms and check_forms, so
  172.                delete it from the list of known objects */
  173.             XDECREF(g->ob_callback);
  174.             g->ob_callback = NULL;
  175.             XDECREF(g->ob_callback_arg);
  176.             g->ob_callback_arg = NULL;
  177.             setlistitem(allgenerics, i, (object *)NULL);
  178.             nfreeslots++;
  179.         }
  180.     }
  181. }
  182.  
  183.  
  184. /* Methods of generic objects */
  185.  
  186. static object *
  187. generic_set_call_back(g, args)
  188.     genericobject *g;
  189.     object *args;
  190. {
  191.     if (args == NULL) {
  192.         XDECREF(g->ob_callback);
  193.         XDECREF(g->ob_callback_arg);
  194.         g->ob_callback = NULL;
  195.         g->ob_callback_arg = NULL;
  196.     }
  197.     else {
  198.         if (!is_tupleobject(args) || gettuplesize(args) != 2) {
  199.             err_badarg();
  200.             return NULL;
  201.         }
  202.         XDECREF(g->ob_callback);
  203.         XDECREF(g->ob_callback_arg);
  204.         g->ob_callback = gettupleitem(args, 0);
  205.         INCREF(g->ob_callback);
  206.         g->ob_callback_arg = gettupleitem(args, 1);
  207.         INCREF(g->ob_callback_arg);
  208.     }
  209.     INCREF(None);
  210.     return None;
  211. }
  212.  
  213. static object *
  214. generic_call(g, args, func)
  215.     genericobject *g;
  216.     object *args;
  217.     void (*func)(FL_OBJECT *);
  218. {
  219.     if (!getnoarg(args))
  220.         return NULL;
  221.     (*func)(g->ob_generic);
  222.     INCREF(None);
  223.     return None;
  224. }
  225.  
  226. static object *
  227. generic_delete_object(g, args)
  228.     genericobject *g;
  229.     object *args;
  230. {
  231.     object *res;
  232.     res = generic_call(g, args, fl_delete_object);
  233.     if (res != NULL)
  234.         forgetgeneric(g);
  235.     return res;
  236. }
  237.  
  238. static object *
  239. generic_show_object(g, args)
  240.     genericobject *g;
  241.     object *args;
  242. {
  243.     return generic_call(g, args, fl_show_object);
  244. }
  245.  
  246. static object *
  247. generic_hide_object(g, args)
  248.     genericobject *g;
  249.     object *args;
  250. {
  251.     return generic_call(g, args, fl_hide_object);
  252. }
  253.  
  254. static object *
  255. generic_redraw_object(g, args)
  256.     genericobject *g;
  257.     object *args;
  258. {
  259.     return generic_call(g, args, fl_redraw_object);
  260. }
  261.  
  262. static object *
  263. generic_freeze_object(g, args)
  264.     genericobject *g;
  265.     object *args;
  266. {
  267.     return generic_call(g, args, fl_freeze_object);
  268. }
  269.  
  270. static object *
  271. generic_unfreeze_object(g, args)
  272.     genericobject *g;
  273.     object *args;
  274. {
  275.     return generic_call(g, args, fl_unfreeze_object);
  276. }
  277.  
  278. static object *
  279. generic_activate_object(g, args)
  280.     genericobject *g;
  281.     object *args;
  282. {
  283.     return generic_call(g, args, fl_activate_object);
  284. }
  285.  
  286. static object *
  287. generic_deactivate_object(g, args)
  288.     genericobject *g;
  289.     object *args;
  290. {
  291.     return generic_call(g, args, fl_deactivate_object);
  292. }
  293.  
  294. static object *
  295. generic_set_object_shortcut(g, args)
  296.     genericobject *g;
  297.     object *args;
  298. {
  299.     char *str;
  300.     if (!getargs(args, "s", &str))
  301.         return NULL;
  302.     fl_set_object_shortcut(g->ob_generic, str);
  303.     INCREF(None);
  304.     return None;
  305. }
  306.  
  307. static struct methodlist generic_methods[] = {
  308.     {"set_call_back",    (method)generic_set_call_back},
  309.     {"delete_object",    (method)generic_delete_object},
  310.     {"show_object",        (method)generic_show_object},
  311.     {"hide_object",        (method)generic_hide_object},
  312.     {"redraw_object",    (method)generic_redraw_object},
  313.     {"freeze_object",    (method)generic_freeze_object},
  314.     {"unfreeze_object",    (method)generic_unfreeze_object},
  315.     {"activate_object",    (method)generic_activate_object},
  316.     {"deactivate_object",    (method)generic_deactivate_object},
  317.     {"set_object_shortcut",    (method)generic_set_object_shortcut},
  318.     {NULL,            NULL}        /* sentinel */
  319. };
  320.  
  321. static void
  322. generic_dealloc(g)
  323.     genericobject *g;
  324. {
  325.     fl_free_object(g->ob_generic);
  326.     XDECREF(g->ob_callback);
  327.     XDECREF(g->ob_callback_arg);
  328.     DEL(g);
  329. }
  330.  
  331. #define OFF(x) offsetof(FL_OBJECT, x)
  332.  
  333. static struct memberlist generic_memberlist[] = {
  334.     {"objclass",    T_INT,        OFF(objclass),    RO},
  335.     {"type",    T_INT,        OFF(type),    RO},
  336.     {"boxtype",    T_INT,        OFF(boxtype)},
  337.     {"x",        T_FLOAT,    OFF(x)},
  338.     {"y",        T_FLOAT,    OFF(y)},
  339.     {"w",        T_FLOAT,    OFF(w)},
  340.     {"h",        T_FLOAT,    OFF(h)},
  341.     {"col1",    T_INT,        OFF(col1)},
  342.     {"col2",    T_INT,        OFF(col2)},
  343.     {"align",    T_INT,        OFF(align)},
  344.     {"lcol",    T_INT,        OFF(lcol)},
  345.     {"lsize",    T_FLOAT,    OFF(lsize)},
  346.     /* "label" is treated specially! */
  347.     {"lstyle",    T_INT,        OFF(lstyle)},
  348.     {"pushed",    T_INT,        OFF(pushed),    RO},
  349.     {"focus",    T_INT,        OFF(focus),    RO},
  350.     {"belowmouse",    T_INT,        OFF(belowmouse),RO},
  351. /*    {"frozen",    T_INT,        OFF(frozen),    RO},    */
  352.     {"active",    T_INT,        OFF(active)},
  353.     {"input",    T_INT,        OFF(input)},
  354.     {"visible",    T_INT,        OFF(visible),    RO},
  355.     {"radio",    T_INT,        OFF(radio)},
  356.     {"automatic",    T_INT,        OFF(automatic)},
  357.     {NULL}    /* Sentinel */
  358. };
  359.  
  360. #undef OFF
  361.  
  362. static object *
  363. generic_getattr(g, name)
  364.     genericobject *g;
  365.     char *name;
  366. {
  367.     object *meth;
  368.  
  369.     /* XXX Ought to special-case name "__methods__" */
  370.     if (g-> ob_methods) {
  371.         meth = findmethod(g->ob_methods, (object *)g, name);
  372.         if (meth != NULL) return meth;
  373.         err_clear();
  374.     }
  375.  
  376.     meth = findmethod(generic_methods, (object *)g, name);
  377.     if (meth != NULL)
  378.         return meth;
  379.     err_clear();
  380.  
  381.     /* "label" is an exception, getmember only works for char pointers,
  382.        not for char arrays */
  383.     if (strcmp(name, "label") == 0)
  384.         return newstringobject(g->ob_generic->label);
  385.  
  386.     return getmember((char *)g->ob_generic, generic_memberlist, name);
  387. }
  388.  
  389. static int
  390. generic_setattr(g, name, v)
  391.     genericobject *g;
  392.     char *name;
  393.     object *v;
  394. {
  395.     int ret;
  396.  
  397.     if (v == NULL) {
  398.         err_setstr(TypeError, "can't delete forms object attributes");
  399.         return -1;
  400.     }
  401.  
  402.     /* "label" is an exception: setmember doesn't set strings;
  403.        and FORMS wants you to call a function to set the label */
  404.     if (strcmp(name, "label") == 0) {
  405.         if (!is_stringobject(v)) {
  406.             err_setstr(TypeError, "label attr must be string");
  407.             return -1;
  408.         }
  409.         fl_set_object_label(g->ob_generic, getstringvalue(v));
  410.         return 0;
  411.     }
  412.  
  413.     ret = setmember((char *)g->ob_generic, generic_memberlist, name, v);
  414.  
  415.     /* Rather than calling all the various set_object_* functions,
  416.        we call fl_redraw_object here.  This is sometimes redundant
  417.        but I doubt that's a big problem */
  418.     if (ret == 0)
  419.         fl_redraw_object(g->ob_generic);
  420.  
  421.     return ret;
  422. }
  423.  
  424. static object *
  425. generic_repr(g)
  426.     genericobject *g;
  427. {
  428.     char buf[100];
  429.     sprintf(buf, "<FORMS_object at %lx, objclass=%d>",
  430.         (long)g, g->ob_generic->objclass);
  431.     return newstringobject(buf);
  432. }
  433.  
  434. static typeobject GenericObjecttype = {
  435.     OB_HEAD_INIT(&Typetype)
  436.     0,                /*ob_size*/
  437.     "FORMS_object",            /*tp_name*/
  438.     sizeof(genericobject),        /*tp_size*/
  439.     0,                /*tp_itemsize*/
  440.     /* methods */
  441.     (destructor)generic_dealloc,    /*tp_dealloc*/
  442.     0,                /*tp_print*/
  443.     (getattrfunc)generic_getattr,    /*tp_getattr*/
  444.     (setattrfunc)generic_setattr,    /*tp_setattr*/
  445.     0,                /*tp_compare*/
  446.     (reprfunc)generic_repr,        /*tp_repr*/
  447. };
  448.  
  449. static object *
  450. newgenericobject(generic, methods)
  451.     FL_OBJECT *generic;
  452.     struct methodlist *methods;
  453. {
  454.     genericobject *g;
  455.     g = NEWOBJ(genericobject, &GenericObjecttype);
  456.     if (g == NULL)
  457.         return NULL;
  458.     g-> ob_generic = generic;
  459.     g->ob_methods = methods;
  460.     g->ob_callback = NULL;
  461.     g->ob_callback_arg = NULL;
  462.     knowgeneric(g);
  463.     return (object *)g;
  464. }
  465.  
  466. /**********************************************************************/
  467. /* Some common calling sequences */
  468.  
  469. /* void func (object, float) */
  470. static object *
  471. call_forms_INf (func, obj, args)
  472.     void (*func)(FL_OBJECT *, float);
  473.     FL_OBJECT *obj;
  474.     object *args;
  475. {
  476.     float parameter;
  477.  
  478.     if (!getargs(args, "f", ¶meter)) return NULL;
  479.  
  480.     (*func) (obj, parameter);
  481.  
  482.     INCREF(None);
  483.     return None;
  484. }
  485.  
  486. /* void func (object, float) */
  487. static object *
  488. call_forms_INfINf (func, obj, args)
  489.     void (*func)(FL_OBJECT *, float, float);
  490.     FL_OBJECT *obj;
  491.     object *args;
  492. {
  493.     float par1, par2;
  494.  
  495.     if (!getargs(args, "(ff)", &par1, &par2)) return NULL;
  496.  
  497.     (*func) (obj, par1, par2);
  498.  
  499.     INCREF(None);
  500.     return None;
  501. }
  502.  
  503. /* void func (object, int) */
  504. static object *
  505. call_forms_INi (func, obj, args)
  506.     void (*func)(FL_OBJECT *, int);
  507.     FL_OBJECT *obj;
  508.     object *args;
  509. {
  510.     int parameter;
  511.  
  512.     if (!getintarg(args, ¶meter)) return NULL;
  513.  
  514.     (*func) (obj, parameter);
  515.  
  516.     INCREF(None);
  517.     return None;
  518. }
  519.  
  520. /* void func (object, char) */
  521. static object *
  522. call_forms_INc (func, obj, args)
  523.     void (*func)(FL_OBJECT *, int);
  524.     FL_OBJECT *obj;
  525.     object *args;
  526. {
  527.     char *a;
  528.  
  529.     if (!getstrarg(args, &a)) return NULL;
  530.  
  531.     (*func) (obj, a[0]);
  532.  
  533.     INCREF(None);
  534.     return None;
  535. }
  536.  
  537. /* void func (object, string) */
  538. static object *
  539. call_forms_INstr (func, obj, args)
  540.     void (*func)(FL_OBJECT *, char *);
  541.     FL_OBJECT *obj;
  542.     object *args;
  543. {
  544.     char *a;
  545.  
  546.     if (!getstrarg(args, &a)) return NULL;
  547.  
  548.     (*func) (obj, a);
  549.  
  550.     INCREF(None);
  551.     return None;
  552. }
  553.  
  554.  
  555. /* void func (object, int, string) */
  556. static object *
  557. call_forms_INiINstr (func, obj, args)
  558.     void (*func)(FL_OBJECT *, int, char *);
  559.     FL_OBJECT *obj;
  560.     object *args;
  561. {
  562.     char *b;
  563.     int a;
  564.     
  565.     if (!getargs(args, "(is)", &a, &b)) return NULL;
  566.     
  567.     (*func) (obj, a, b);
  568.     
  569.     INCREF(None);
  570.     return None;
  571. }
  572.  
  573. #ifdef UNUSED
  574. /* void func (object, int, int) */
  575. static object *
  576. call_forms_INiINi (func, obj, args)
  577.     void (*func)(FL_OBJECT *, int, int);
  578.     FL_OBJECT *obj;
  579.     object *args;
  580. {
  581.     int par1, par2;
  582.     
  583.     if (!getargs(args, "(ii)", &par1, &par2)) return NULL;
  584.     
  585.     (*func) (obj, par1, par2);
  586.     
  587.     INCREF(None);
  588.     return None;
  589. }
  590. #endif
  591.  
  592. /* int func (object) */
  593. static object *
  594. call_forms_Ri (func, obj, args)
  595.     int (*func)(FL_OBJECT *);
  596.     FL_OBJECT *obj;
  597.     object *args;
  598. {
  599.     int retval;
  600.     
  601.     if (!getnoarg(args)) return NULL;
  602.     
  603.     retval = (*func) (obj);
  604.     
  605.     return newintobject ((long) retval);
  606. }
  607.  
  608. /* char * func (object) */
  609. static object *
  610. call_forms_Rstr (func, obj, args)
  611.     char * (*func)(FL_OBJECT *);
  612.     FL_OBJECT *obj;
  613.     object *args;
  614. {
  615.     char *str;
  616.     
  617.     if (!getnoarg(args)) return NULL;
  618.     
  619.     str = (*func) (obj);
  620.     
  621.     if (str == NULL) {
  622.         INCREF(None);
  623.         return None;
  624.     }
  625.     return newstringobject (str);
  626. }
  627.  
  628. /* int func (object) */
  629. static object *
  630. call_forms_Rf (func, obj, args)
  631.     float (*func)(FL_OBJECT *);
  632.     FL_OBJECT *obj;
  633.     object *args;
  634. {
  635.     float retval;
  636.     
  637.     if (!getnoarg(args)) return NULL;
  638.     
  639.     retval = (*func) (obj);
  640.     
  641.     return newfloatobject (retval);
  642. }
  643.  
  644. static object *
  645. call_forms_OUTfOUTf (func, obj, args)
  646.     void (*func)(FL_OBJECT *, float *, float *);
  647.     FL_OBJECT *obj;
  648.     object *args;
  649. {
  650.     float f1, f2;
  651.     
  652.     if (!getnoarg(args)) return NULL;
  653.     
  654.     (*func) (obj, &f1, &f2);
  655.  
  656.     return mkvalue("(ff)", f1, f2);
  657. }
  658.  
  659. #ifdef UNUSED
  660. static object *
  661. call_forms_OUTf (func, obj, args)
  662.     void (*func)(FL_OBJECT *, float *);
  663.     FL_OBJECT *obj;
  664.     object *args;
  665. {
  666.     float f;
  667.  
  668.     if (!getnoarg(args)) return NULL;
  669.  
  670.     (*func) (obj, &f);
  671.  
  672.     return newfloatobject (f);
  673. }
  674. #endif
  675.  
  676. /**********************************************************************/
  677. /* Class : browser */
  678.  
  679. static object *
  680. set_browser_topline(g, args)
  681.     genericobject *g;
  682.     object *args;
  683. {
  684.     return call_forms_INi (fl_set_browser_topline, g-> ob_generic, args);
  685. }
  686.  
  687. static object *
  688. clear_browser(g, args)
  689.     genericobject *g;
  690.     object *args;
  691. {
  692.     return generic_call (g, args, fl_clear_browser);
  693. }
  694.  
  695. static object *
  696. add_browser_line (g, args)
  697.     genericobject *g;
  698.     object *args;
  699. {
  700.     return call_forms_INstr (fl_add_browser_line, g-> ob_generic, args);
  701. }
  702.  
  703. static object *
  704. addto_browser (g, args)
  705.     genericobject *g;
  706.     object *args;
  707. {
  708.     return call_forms_INstr (fl_addto_browser, g-> ob_generic, args);
  709. }
  710.  
  711. static object *
  712. insert_browser_line (g, args)
  713.     genericobject *g;
  714.     object *args;
  715. {
  716.     return call_forms_INiINstr (fl_insert_browser_line,
  717.                     g-> ob_generic, args);
  718. }
  719.  
  720. static object *
  721. delete_browser_line (g, args)
  722.     genericobject *g;
  723.     object *args;
  724. {
  725.     return call_forms_INi (fl_delete_browser_line, g-> ob_generic, args);
  726. }
  727.  
  728. static object *
  729. replace_browser_line (g, args)
  730.     genericobject *g;
  731.     object *args;
  732. {
  733.     return call_forms_INiINstr (fl_replace_browser_line,
  734.                     g-> ob_generic, args);
  735. }
  736.  
  737. static object *
  738. get_browser_line(g, args)
  739.     genericobject *g;
  740.     object *args;
  741. {
  742.     int i;
  743.     char *str;
  744.  
  745.     if (!getintarg(args, &i))
  746.         return NULL;
  747.  
  748.     str = fl_get_browser_line (g->ob_generic, i);
  749.  
  750.     if (str == NULL) {
  751.         INCREF(None);
  752.         return None;
  753.     }
  754.     return newstringobject (str);
  755. }
  756.  
  757. static object *
  758. load_browser (g, args)
  759.     genericobject *g;
  760.     object *args;
  761. {
  762.     /* XXX strictly speaking this is wrong since fl_load_browser
  763.        XXX returns int, not void */
  764.     return call_forms_INstr (fl_load_browser, g-> ob_generic, args);
  765. }
  766.  
  767. static object *
  768. get_browser_maxline(g, args)
  769.     genericobject *g;
  770.     object *args;
  771. {
  772.     return call_forms_Ri (fl_get_browser_maxline, g-> ob_generic, args);
  773. }
  774.  
  775. static object *
  776. select_browser_line (g, args)
  777.     genericobject *g;
  778.     object *args;
  779. {
  780.     return call_forms_INi (fl_select_browser_line, g-> ob_generic, args);
  781. }
  782.  
  783. static object *
  784. deselect_browser_line (g, args)
  785.     genericobject *g;
  786.     object *args;
  787. {
  788.     return call_forms_INi (fl_deselect_browser_line, g-> ob_generic, args);
  789. }
  790.  
  791. static object *
  792. deselect_browser (g, args)
  793.     genericobject *g;
  794.     object *args;
  795. {
  796.     return generic_call (g, args, fl_deselect_browser);
  797. }
  798.  
  799. static object *
  800. isselected_browser_line (g, args)
  801.     genericobject *g;
  802.     object *args;
  803. {
  804.     int i, j;
  805.     
  806.     if (!getintarg(args, &i))
  807.         return NULL;
  808.     
  809.     j = fl_isselected_browser_line (g->ob_generic, i);
  810.     
  811.     return newintobject (j);
  812. }
  813.  
  814. static object *
  815. get_browser (g, args)
  816.     genericobject *g;
  817.     object *args;
  818. {
  819.     return call_forms_Ri (fl_get_browser, g-> ob_generic, args);
  820. }
  821.  
  822. static object *
  823. set_browser_fontsize (g, args)
  824.     genericobject *g;
  825.     object *args;
  826. {
  827.     return call_forms_INf (fl_set_browser_fontsize, g-> ob_generic, args);
  828. }
  829.  
  830. static object *
  831. set_browser_fontstyle (g, args)
  832.     genericobject *g;
  833.     object *args;
  834. {
  835.     return call_forms_INi (fl_set_browser_fontstyle, g-> ob_generic, args);
  836. }
  837.  
  838. static object *
  839. set_browser_specialkey (g, args)
  840.     genericobject *g;
  841.     object *args;
  842. {
  843.     return call_forms_INc(fl_set_browser_specialkey, g-> ob_generic, args);
  844. }
  845.  
  846. static struct methodlist browser_methods[] = {
  847.     {"set_browser_topline",        (method)set_browser_topline},
  848.     {"clear_browser",        (method)clear_browser},
  849.     {"add_browser_line",        (method)add_browser_line},
  850.     {"addto_browser",        (method)addto_browser},
  851.     {"insert_browser_line",        (method)insert_browser_line},
  852.     {"delete_browser_line",        (method)delete_browser_line},
  853.     {"replace_browser_line",    (method)replace_browser_line},
  854.     {"get_browser_line",        (method)get_browser_line},
  855.     {"load_browser",        (method)load_browser},
  856.     {"get_browser_maxline",        (method)get_browser_maxline},
  857.     {"select_browser_line",        (method)select_browser_line},
  858.     {"deselect_browser_line",    (method)deselect_browser_line},
  859.     {"deselect_browser",        (method)deselect_browser},
  860.     {"isselected_browser_line",    (method)isselected_browser_line},
  861.     {"get_browser",            (method)get_browser},
  862.     {"set_browser_fontsize",    (method)set_browser_fontsize},
  863.     {"set_browser_fontstyle",    (method)set_browser_fontstyle},
  864.     {"set_browser_specialkey",    (method)set_browser_specialkey},
  865.     {NULL,                NULL}        /* sentinel */
  866. };
  867.  
  868. /* Class: button */
  869.  
  870. static object *
  871. set_button(g, args)
  872.     genericobject *g;
  873.     object *args;
  874. {
  875.     return call_forms_INi (fl_set_button, g-> ob_generic, args);
  876. }
  877.  
  878. static object *
  879. get_button(g, args)
  880.     genericobject *g;
  881.     object *args;
  882. {
  883.     return call_forms_Ri (fl_get_button, g-> ob_generic, args);
  884. }
  885.  
  886. static object *
  887. get_button_numb(g, args)
  888.     genericobject *g;
  889.     object *args;
  890. {
  891.     return call_forms_Ri (fl_get_button_numb, g-> ob_generic, args);
  892. }
  893.  
  894. static object *
  895. set_button_shortcut(g, args)
  896.     genericobject *g;
  897.     object *args;
  898. {
  899.     return call_forms_INstr (fl_set_button_shortcut, g-> ob_generic, args);
  900. }
  901.  
  902. static struct methodlist button_methods[] = {
  903.     {"set_button",        (method)set_button},
  904.     {"get_button",        (method)get_button},
  905.     {"get_button_numb",    (method)get_button_numb},
  906.     {"set_button_shortcut",    (method)set_button_shortcut},
  907.     {NULL,            NULL}        /* sentinel */
  908. };
  909.  
  910. /* Class: choice */
  911.  
  912. static object *
  913. set_choice(g, args)
  914.     genericobject *g;
  915.     object *args;
  916. {
  917.     return call_forms_INi (fl_set_choice, g-> ob_generic, args);
  918. }
  919.  
  920. static object *
  921. get_choice(g, args)
  922.     genericobject *g;
  923.     object *args;
  924. {
  925.     return call_forms_Ri (fl_get_choice, g-> ob_generic, args);
  926. }
  927.  
  928. static object *
  929. clear_choice (g, args)
  930.     genericobject *g;
  931.     object *args;
  932. {
  933.     return generic_call (g, args, fl_clear_choice);
  934. }
  935.  
  936. static object *
  937. addto_choice (g, args)
  938.     genericobject *g;
  939.     object *args;
  940. {
  941.     return call_forms_INstr (fl_addto_choice, g-> ob_generic, args);
  942. }
  943.  
  944. static object *
  945. replace_choice (g, args)
  946.     genericobject *g;
  947.     object *args;
  948. {
  949.     return call_forms_INiINstr (fl_replace_choice, g-> ob_generic, args);
  950. }
  951.  
  952. static object *
  953. delete_choice (g, args)
  954.     genericobject *g;
  955.     object *args;
  956. {
  957.     return call_forms_INi (fl_delete_choice, g-> ob_generic, args);
  958. }
  959.  
  960. static object *
  961. get_choice_text (g, args)
  962.     genericobject *g;
  963.     object *args;
  964. {
  965.     return call_forms_Rstr (fl_get_choice_text, g-> ob_generic, args);
  966. }
  967.  
  968. static object *
  969. set_choice_fontsize (g, args)
  970.     genericobject *g;
  971.     object *args;
  972. {
  973.     return call_forms_INf (fl_set_choice_fontsize, g-> ob_generic, args);
  974. }
  975.  
  976. static object *
  977. set_choice_fontstyle (g, args)
  978.     genericobject *g;
  979.     object *args;
  980. {
  981.     return call_forms_INi (fl_set_choice_fontstyle, g-> ob_generic, args);
  982. }
  983.  
  984. static struct methodlist choice_methods[] = {
  985.     {"set_choice",        (method)set_choice},
  986.     {"get_choice",        (method)get_choice},
  987.     {"clear_choice",    (method)clear_choice},
  988.     {"addto_choice",    (method)addto_choice},
  989.     {"replace_choice",    (method)replace_choice},
  990.     {"delete_choice",    (method)delete_choice},
  991.     {"get_choice_text",    (method)get_choice_text},
  992.     {"set_choice_fontsize", (method)set_choice_fontsize},
  993.     {"set_choice_fontstyle",(method)set_choice_fontstyle},
  994.     {NULL,            NULL}        /* sentinel */
  995. };
  996.  
  997. /* Class : Clock */
  998.  
  999. static object *
  1000. get_clock(g, args)
  1001.     genericobject *g;
  1002.     object *args;
  1003. {
  1004.     int i0, i1, i2;
  1005.  
  1006.     if (!getnoarg(args))
  1007.         return NULL;
  1008.  
  1009.     fl_get_clock (g->ob_generic, &i0, &i1, &i2);
  1010.  
  1011.     return mkvalue("(iii)", i0, i1, i2);
  1012. }
  1013.  
  1014. static struct methodlist clock_methods[] = {
  1015.     {"get_clock",        (method)get_clock},
  1016.     {NULL,            NULL}        /* sentinel */
  1017. };
  1018.  
  1019. /* CLass : Counters */
  1020.  
  1021. static object *
  1022. get_counter_value(g, args)
  1023.     genericobject *g;
  1024.     object *args;
  1025. {
  1026.     return call_forms_Rf (fl_get_counter_value, g-> ob_generic, args);
  1027. }
  1028.  
  1029. static object *
  1030. set_counter_value (g, args)
  1031.     genericobject *g;
  1032.     object *args;
  1033. {
  1034.     return call_forms_INf (fl_set_counter_value, g-> ob_generic, args);
  1035. }
  1036.  
  1037. static object *
  1038. set_counter_precision (g, args)
  1039.     genericobject *g;
  1040.     object *args;
  1041. {
  1042.     return call_forms_INi (fl_set_counter_precision, g-> ob_generic, args);
  1043. }
  1044.  
  1045. static object *
  1046. set_counter_bounds (g, args)
  1047.     genericobject *g;
  1048.     object *args;
  1049. {
  1050.     return call_forms_INfINf (fl_set_counter_bounds, g-> ob_generic, args);
  1051. }
  1052.  
  1053. static object *
  1054. set_counter_step (g, args)
  1055.     genericobject *g;
  1056.     object *args;
  1057. {
  1058.     return call_forms_INfINf (fl_set_counter_step, g-> ob_generic, args);
  1059. }
  1060.  
  1061. static object *
  1062. set_counter_return (g, args)
  1063.     genericobject *g;
  1064.     object *args;
  1065. {
  1066.     return call_forms_INi (fl_set_counter_return, g-> ob_generic, args);
  1067. }
  1068.  
  1069. static struct methodlist counter_methods[] = {
  1070.     {"set_counter_value",        (method)set_counter_value},
  1071.     {"get_counter_value",        (method)get_counter_value},
  1072.     {"set_counter_bounds",        (method)set_counter_bounds},
  1073.     {"set_counter_step",        (method)set_counter_step},
  1074.     {"set_counter_precision",    (method)set_counter_precision},
  1075.     {"set_counter_return",        (method)set_counter_return},
  1076.     {NULL,                NULL}        /* sentinel */
  1077. };
  1078.  
  1079.  
  1080. /* Class: Dials */
  1081.  
  1082. static object *
  1083. get_dial_value(g, args)
  1084.     genericobject *g;
  1085.     object *args;
  1086. {
  1087.     return call_forms_Rf (fl_get_dial_value, g-> ob_generic, args);
  1088. }
  1089.  
  1090. static object *
  1091. set_dial_value (g, args)
  1092.     genericobject *g;
  1093.     object *args;
  1094. {
  1095.     return call_forms_INf (fl_set_dial_value, g-> ob_generic, args);
  1096. }
  1097.  
  1098. static object *
  1099. set_dial_bounds (g, args)
  1100.     genericobject *g;
  1101.     object *args;
  1102. {
  1103.     return call_forms_INfINf (fl_set_dial_bounds, g-> ob_generic, args);
  1104. }
  1105.  
  1106. static object *
  1107. get_dial_bounds (g, args)
  1108.     genericobject *g;
  1109.     object *args;
  1110. {
  1111.     return call_forms_OUTfOUTf (fl_get_dial_bounds, g-> ob_generic, args);
  1112. }
  1113.  
  1114. static object *
  1115. set_dial_step (g, args)
  1116.     genericobject *g;
  1117.     object *args;
  1118. {
  1119.     return call_forms_INf (fl_set_dial_step, g-> ob_generic, args);
  1120. }
  1121.  
  1122. static struct methodlist dial_methods[] = {
  1123.     {"set_dial_value",    (method)set_dial_value},
  1124.     {"get_dial_value",    (method)get_dial_value},
  1125.     {"set_dial_bounds",    (method)set_dial_bounds},
  1126.     {"get_dial_bounds",    (method)get_dial_bounds},
  1127.     {"set_dial_step",    (method)set_dial_step},
  1128.     {NULL,            NULL}        /* sentinel */
  1129. };
  1130.  
  1131. /* Class : Input */
  1132.  
  1133. static object *
  1134. set_input (g, args)
  1135.     genericobject *g;
  1136.     object *args;
  1137. {
  1138.     return call_forms_INstr (fl_set_input, g-> ob_generic, args);
  1139. }
  1140.  
  1141. static object *
  1142. get_input (g, args)
  1143.     genericobject *g;
  1144.     object *args;
  1145. {
  1146.     return call_forms_Rstr (fl_get_input, g-> ob_generic, args);
  1147. }
  1148.  
  1149. static object *
  1150. set_input_color (g, args)
  1151.     genericobject *g;
  1152.     object *args;
  1153. {
  1154.     return call_forms_INfINf (fl_set_input_color, g-> ob_generic, args);
  1155. }
  1156.  
  1157. static object *
  1158. set_input_return (g, args)
  1159.     genericobject *g;
  1160.     object *args;
  1161. {
  1162.     return call_forms_INi (fl_set_input_return, g-> ob_generic, args);
  1163. }
  1164.  
  1165. static struct methodlist input_methods[] = {
  1166.     {"set_input",        (method)set_input},
  1167.     {"get_input",        (method)get_input},
  1168.     {"set_input_color",    (method)set_input_color},
  1169.     {"set_input_return",    (method)set_input_return},
  1170.     {NULL,            NULL}        /* sentinel */
  1171. };
  1172.  
  1173.  
  1174. /* Class : Menu */
  1175.  
  1176. static object *
  1177. set_menu (g, args)
  1178.     genericobject *g;
  1179.     object *args;
  1180. {
  1181.     return call_forms_INstr (fl_set_menu, g-> ob_generic, args);
  1182. }
  1183.  
  1184. static object *
  1185. get_menu (g, args)
  1186.     genericobject *g;
  1187.     object *args;
  1188. {
  1189.     /* XXX strictly speaking this is wrong since fl_get_menu
  1190.        XXX returns long, not int */
  1191.     return call_forms_Ri (fl_get_menu, g-> ob_generic, args);
  1192. }
  1193.  
  1194. static object *
  1195. get_menu_text (g, args)
  1196.     genericobject *g;
  1197.     object *args;
  1198. {
  1199.     return call_forms_Rstr (fl_get_menu_text, g-> ob_generic, args);
  1200. }
  1201.  
  1202. static object *
  1203. addto_menu (g, args)
  1204.     genericobject *g;
  1205.     object *args;
  1206. {
  1207.     return call_forms_INstr (fl_addto_menu, g-> ob_generic, args);
  1208. }
  1209.  
  1210. static struct methodlist menu_methods[] = {
  1211.     {"set_menu",        (method)set_menu},
  1212.     {"get_menu",        (method)get_menu},
  1213.     {"get_menu_text",    (method)get_menu_text},
  1214.     {"addto_menu",        (method)addto_menu},
  1215.     {NULL,            NULL}        /* sentinel */
  1216. };
  1217.  
  1218.  
  1219. /* Class: Sliders */
  1220.  
  1221. static object *
  1222. get_slider_value(g, args)
  1223.     genericobject *g;
  1224.     object *args;
  1225. {
  1226.     return call_forms_Rf (fl_get_slider_value, g-> ob_generic, args);
  1227. }
  1228.  
  1229. static object *
  1230. set_slider_value (g, args)
  1231.     genericobject *g;
  1232.     object *args;
  1233. {
  1234.     return call_forms_INf (fl_set_slider_value, g-> ob_generic, args);
  1235. }
  1236.  
  1237. static object *
  1238. set_slider_bounds (g, args)
  1239.     genericobject *g;
  1240.     object *args;
  1241. {
  1242.     return call_forms_INfINf (fl_set_slider_bounds, g-> ob_generic, args);
  1243. }
  1244.  
  1245. static object *
  1246. get_slider_bounds (g, args)
  1247.     genericobject *g;
  1248.     object *args;
  1249. {
  1250.     return call_forms_OUTfOUTf(fl_get_slider_bounds, g-> ob_generic, args);
  1251. }
  1252.  
  1253. static object *
  1254. set_slider_return (g, args)
  1255.     genericobject *g;
  1256.     object *args;
  1257. {
  1258.     return call_forms_INf (fl_set_slider_return, g-> ob_generic, args);
  1259. }
  1260.  
  1261. static object *
  1262. set_slider_size (g, args)
  1263.     genericobject *g;
  1264.     object *args;
  1265. {
  1266.     return call_forms_INf (fl_set_slider_size, g-> ob_generic, args);
  1267. }
  1268.  
  1269. static object *
  1270. set_slider_precision (g, args)
  1271.     genericobject *g;
  1272.     object *args;
  1273. {
  1274.     return call_forms_INi (fl_set_slider_precision, g-> ob_generic, args);
  1275. }
  1276.  
  1277. static object *
  1278. set_slider_step (g, args)
  1279.     genericobject *g;
  1280.     object *args;
  1281. {
  1282.     return call_forms_INf (fl_set_slider_step, g-> ob_generic, args);
  1283. }
  1284.  
  1285.  
  1286. static struct methodlist slider_methods[] = {
  1287.     {"set_slider_value",    (method)set_slider_value},
  1288.     {"get_slider_value",    (method)get_slider_value},
  1289.     {"set_slider_bounds",    (method)set_slider_bounds},
  1290.     {"get_slider_bounds",    (method)get_slider_bounds},
  1291.     {"set_slider_return",    (method)set_slider_return},
  1292.     {"set_slider_size",    (method)set_slider_size},
  1293.     {"set_slider_precision",(method)set_slider_precision},
  1294.     {"set_slider_step",    (method)set_slider_step},
  1295.     {NULL,            NULL}        /* sentinel */
  1296. };
  1297.  
  1298. static object *
  1299. set_positioner_xvalue (g, args)
  1300.     genericobject *g;
  1301.     object *args;
  1302. {
  1303.     return call_forms_INf (fl_set_positioner_xvalue, g-> ob_generic, args);
  1304. }
  1305.  
  1306. static object *
  1307. set_positioner_xbounds (g, args)
  1308.     genericobject *g;
  1309.     object *args;
  1310. {
  1311.     return call_forms_INfINf (fl_set_positioner_xbounds,
  1312.                   g-> ob_generic, args);
  1313. }
  1314.  
  1315. static object *
  1316. set_positioner_yvalue (g, args)
  1317.     genericobject *g;
  1318.     object *args;
  1319. {
  1320.     return call_forms_INf (fl_set_positioner_yvalue, g-> ob_generic, args);
  1321. }
  1322.  
  1323. static object *
  1324. set_positioner_ybounds (g, args)
  1325.     genericobject *g;
  1326.     object *args;
  1327. {
  1328.     return call_forms_INfINf (fl_set_positioner_ybounds,
  1329.                   g-> ob_generic, args);
  1330. }
  1331.  
  1332. static object *
  1333. get_positioner_xvalue (g, args)
  1334.     genericobject *g;
  1335.     object *args;
  1336. {
  1337.     return call_forms_Rf (fl_get_positioner_xvalue, g-> ob_generic, args);
  1338. }
  1339.  
  1340. static object *
  1341. get_positioner_xbounds (g, args)
  1342.     genericobject *g;
  1343.     object *args;
  1344. {
  1345.     return call_forms_OUTfOUTf (fl_get_positioner_xbounds,
  1346.                     g-> ob_generic, args);
  1347. }
  1348.  
  1349. static object *
  1350. get_positioner_yvalue (g, args)
  1351.     genericobject *g;
  1352.     object *args;
  1353. {
  1354.     return call_forms_Rf (fl_get_positioner_yvalue, g-> ob_generic, args);
  1355. }
  1356.  
  1357. static object *
  1358. get_positioner_ybounds (g, args)
  1359.     genericobject *g;
  1360.     object *args;
  1361. {
  1362.     return call_forms_OUTfOUTf (fl_get_positioner_ybounds,
  1363.                     g-> ob_generic, args);
  1364. }
  1365.  
  1366. static struct methodlist positioner_methods[] = {
  1367.     {"set_positioner_xvalue",    (method)set_positioner_xvalue},
  1368.     {"set_positioner_yvalue",    (method)set_positioner_yvalue},
  1369.     {"set_positioner_xbounds",    (method)set_positioner_xbounds},
  1370.     {"set_positioner_ybounds",    (method)set_positioner_ybounds},
  1371.     {"get_positioner_xvalue",    (method)get_positioner_xvalue},
  1372.     {"get_positioner_yvalue",    (method)get_positioner_yvalue},
  1373.     {"get_positioner_xbounds",    (method)get_positioner_xbounds},
  1374.     {"get_positioner_ybounds",    (method)get_positioner_ybounds},
  1375.     {NULL,            NULL}        /* sentinel */
  1376. };
  1377.  
  1378. /* Class timer */
  1379.  
  1380. static object *
  1381. set_timer (g, args)
  1382.     genericobject *g;
  1383.     object *args;
  1384. {
  1385.     return call_forms_INf (fl_set_timer, g-> ob_generic, args);
  1386. }
  1387.  
  1388. static object *
  1389. get_timer (g, args)
  1390.     genericobject *g;
  1391.     object *args;
  1392. {
  1393.     return call_forms_Rf (fl_get_timer, g-> ob_generic, args);
  1394. }
  1395.  
  1396. static struct methodlist timer_methods[] = {
  1397.     {"set_timer",        (method)set_timer},
  1398.     {"get_timer",        (method)get_timer},
  1399.     {NULL,            NULL}        /* sentinel */
  1400. };
  1401.  
  1402. /* Form objects */
  1403.  
  1404. typedef struct {
  1405.     OB_HEAD
  1406.     FL_FORM *ob_form;
  1407. } formobject;
  1408.  
  1409. staticforward typeobject Formtype;
  1410.  
  1411. #define is_formobject(v) ((v)->ob_type == &Formtype)
  1412.  
  1413. static object *
  1414. form_show_form(f, args)
  1415.     formobject *f;
  1416.     object *args;
  1417. {
  1418.     int place, border;
  1419.     char *name;
  1420.     if (!getargs(args, "(iis)", &place, &border, &name))
  1421.         return NULL;
  1422.     fl_show_form(f->ob_form, place, border, name);
  1423.     INCREF(None);
  1424.     return None;
  1425. }
  1426.  
  1427. static object *
  1428. form_call(func, f, args)
  1429.     FL_FORM *f;
  1430.     object *args;
  1431.     void (*func)(FL_FORM *);
  1432. {
  1433.     if (!getnoarg(args)) return NULL;
  1434.  
  1435.     (*func)(f);
  1436.  
  1437.     INCREF(None);
  1438.     return None;
  1439. }
  1440.  
  1441. static object *
  1442. form_call_INiINi(func, f, args)
  1443.     FL_FORM *f;
  1444.     object *args;
  1445.     void (*func)(FL_FORM *, int, int);
  1446. {
  1447.     int a, b;
  1448.  
  1449.     if (!getargs(args, "(ii)", &a, &b)) return NULL;
  1450.  
  1451.     (*func)(f, a, b);
  1452.  
  1453.     INCREF(None);
  1454.     return None;
  1455. }
  1456.  
  1457. static object *
  1458. form_call_INfINf(func, f, args)
  1459.     FL_FORM *f;
  1460.     object *args;
  1461.     void (*func)(FL_FORM *, float, float);
  1462. {
  1463.     float a, b;
  1464.  
  1465.     if (!getargs(args, "(ff)", &a, &b)) return NULL;
  1466.  
  1467.     (*func)(f, a, b);
  1468.  
  1469.     INCREF(None);
  1470.     return None;
  1471. }
  1472.  
  1473. static object *
  1474. form_hide_form(f, args)
  1475.     formobject *f;
  1476.     object *args;
  1477. {
  1478.     return form_call(fl_hide_form, f-> ob_form, args);
  1479. }
  1480.  
  1481. static object *
  1482. form_redraw_form(f, args)
  1483.     formobject *f;
  1484.     object *args;
  1485. {
  1486.     return form_call(fl_redraw_form, f-> ob_form, args);
  1487. }
  1488.  
  1489. static object *
  1490. form_add_object(f, args)
  1491.     formobject *f;
  1492.     object *args;
  1493. {
  1494.     genericobject *g;
  1495.     if (args == NULL || !is_genericobject(args)) {
  1496.         err_badarg();
  1497.         return NULL;
  1498.     }
  1499.     g = (genericobject *)args;
  1500.     if (findgeneric(g->ob_generic) != NULL) {
  1501.         err_setstr(RuntimeError,
  1502.                "add_object of object already in a form");
  1503.         return NULL;
  1504.     }
  1505.     fl_add_object(f->ob_form, g->ob_generic);
  1506.     knowgeneric(g);
  1507.  
  1508.     INCREF(None);
  1509.     return None;
  1510. }
  1511.  
  1512. static object *
  1513. form_set_form_position(f, args)
  1514.     formobject *f;
  1515.     object *args;
  1516. {
  1517.     return form_call_INiINi(fl_set_form_position, f-> ob_form, args);
  1518. }
  1519.  
  1520. static object *
  1521. form_set_form_size(f, args)
  1522.     formobject *f;
  1523.     object *args;
  1524. {
  1525.     return form_call_INiINi(fl_set_form_size, f-> ob_form, args);
  1526. }
  1527.  
  1528. static object *
  1529. form_scale_form(f, args)
  1530.     formobject *f;
  1531.     object *args;
  1532. {
  1533.     return form_call_INfINf(fl_scale_form, f-> ob_form, args);
  1534. }
  1535.  
  1536. static object *
  1537. generic_add_object(f, args, func, internal_methods)
  1538.     formobject *f;
  1539.     object *args;
  1540.     FL_OBJECT *(*func)(int, float, float, float, float, char*);
  1541.     struct methodlist *internal_methods;
  1542. {
  1543.     int type;
  1544.     float x, y, w, h;
  1545.     char *name;
  1546.     FL_OBJECT *obj;
  1547.  
  1548.     if (!getargs(args,"(iffffs)", &type,&x,&y,&w,&h,&name))
  1549.         return NULL;
  1550.  
  1551.     fl_addto_form (f-> ob_form);
  1552.  
  1553.     obj = (*func) (type, x, y, w, h, name);
  1554.  
  1555.     fl_end_form();
  1556.  
  1557.     if (obj == NULL) {
  1558.         err_nomem();
  1559.         return NULL;
  1560.     }
  1561.  
  1562.     return newgenericobject (obj, internal_methods);
  1563. }
  1564.  
  1565. static object *
  1566. form_add_button(f, args)
  1567.     formobject *f;
  1568.     object *args;
  1569. {
  1570.     return generic_add_object(f, args, fl_add_button, button_methods);
  1571. }
  1572.  
  1573. static object *
  1574. form_add_lightbutton(f, args)
  1575.     formobject *f;
  1576.     object *args;
  1577. {
  1578.     return generic_add_object(f, args, fl_add_lightbutton, button_methods);
  1579. }
  1580.  
  1581. static object *
  1582. form_add_roundbutton(f, args)
  1583.     formobject *f;
  1584.     object *args;
  1585. {
  1586.     return generic_add_object(f, args, fl_add_roundbutton, button_methods);
  1587. }
  1588.  
  1589. static object *
  1590. form_add_menu (f, args)
  1591.     formobject *f;
  1592.     object *args;
  1593. {
  1594.     return generic_add_object(f, args, fl_add_menu, menu_methods);
  1595. }
  1596.  
  1597. static object *
  1598. form_add_slider(f, args)
  1599.     formobject *f;
  1600.     object *args;
  1601. {
  1602.     return generic_add_object(f, args, fl_add_slider, slider_methods);
  1603. }
  1604.  
  1605. static object *
  1606. form_add_valslider(f, args)
  1607.     formobject *f;
  1608.     object *args;
  1609. {
  1610.     return generic_add_object(f, args, fl_add_valslider, slider_methods);
  1611. }
  1612.  
  1613. static object *
  1614. form_add_dial(f, args)
  1615.     formobject *f;
  1616.     object *args;
  1617. {
  1618.     return generic_add_object(f, args, fl_add_dial, dial_methods);
  1619. }
  1620.  
  1621. static object *
  1622. form_add_counter(f, args)
  1623.     formobject *f;
  1624.     object *args;
  1625. {
  1626.     return generic_add_object(f, args, fl_add_counter, counter_methods);
  1627. }
  1628.  
  1629. static object *
  1630. form_add_clock(f, args)
  1631.     formobject *f;
  1632.     object *args;
  1633. {
  1634.     return generic_add_object(f, args, fl_add_clock, clock_methods);
  1635. }
  1636.  
  1637. static object *
  1638. form_add_box(f, args)
  1639.     formobject *f;
  1640.     object *args;
  1641. {
  1642.     return generic_add_object(f, args, fl_add_box,
  1643.                   (struct methodlist *)NULL);
  1644. }
  1645.  
  1646. static object *
  1647. form_add_choice(f, args)
  1648.     formobject *f;
  1649.     object *args;
  1650. {
  1651.     return generic_add_object(f, args, fl_add_choice, choice_methods);
  1652. }
  1653.  
  1654. static object *
  1655. form_add_browser(f, args)
  1656.     formobject *f;
  1657.     object *args;
  1658. {
  1659.     return generic_add_object(f, args, fl_add_browser, browser_methods);
  1660. }
  1661.  
  1662. static object *
  1663. form_add_positioner(f, args)
  1664.     formobject *f;
  1665.     object *args;
  1666. {
  1667.     return generic_add_object(f, args, fl_add_positioner, positioner_methods);
  1668. }
  1669.  
  1670. static object *
  1671. form_add_input(f, args)
  1672.     formobject *f;
  1673.     object *args;
  1674. {
  1675.     return generic_add_object(f, args, fl_add_input, input_methods);
  1676. }
  1677.  
  1678. static object *
  1679. form_add_text(f, args)
  1680.     formobject *f;
  1681.     object *args;
  1682. {
  1683.     return generic_add_object(f, args, fl_add_text,
  1684.                   (struct methodlist *)NULL);
  1685. }
  1686.  
  1687. static object *
  1688. form_add_timer(f, args)
  1689.     formobject *f;
  1690.     object *args;
  1691. {
  1692.     return generic_add_object(f, args, fl_add_timer, timer_methods);
  1693. }
  1694.  
  1695. static object *
  1696. form_freeze_form(f, args)
  1697.     formobject *f;
  1698.     object *args;
  1699. {
  1700.     return form_call(fl_freeze_form, f-> ob_form, args);
  1701. }
  1702.  
  1703. static object *
  1704. form_unfreeze_form(f, args)
  1705.     formobject *f;
  1706.     object *args;
  1707. {
  1708.     return form_call(fl_unfreeze_form, f-> ob_form, args);
  1709. }
  1710.  
  1711. static object *
  1712. form_activate_form(f, args)
  1713.     formobject *f;
  1714.     object *args;
  1715. {
  1716.     return form_call(fl_activate_form, f-> ob_form, args);
  1717. }
  1718.  
  1719. static object *
  1720. form_deactivate_form(f, args)
  1721.     formobject *f;
  1722.     object *args;
  1723. {
  1724.     return form_call(fl_deactivate_form, f-> ob_form, args);
  1725. }
  1726.  
  1727. static object *
  1728. form_bgn_group(f, args)
  1729.     formobject *f;
  1730.     object *args;
  1731. {
  1732.     FL_OBJECT *obj;
  1733.  
  1734.     fl_addto_form(f-> ob_form);
  1735.     obj = fl_bgn_group();
  1736.     fl_end_form();
  1737.  
  1738.     if (obj == NULL) {
  1739.         err_nomem();
  1740.         return NULL;
  1741.     }
  1742.  
  1743.     return newgenericobject (obj, (struct methodlist *) NULL);
  1744. }
  1745.  
  1746. static object *
  1747. form_end_group(f, args)
  1748.     formobject *f;
  1749.     object *args;
  1750. {
  1751.     fl_addto_form(f-> ob_form);
  1752.     fl_end_group();
  1753.     fl_end_form();
  1754.     INCREF(None);
  1755.     return None;
  1756. }
  1757.  
  1758. static object *
  1759. forms_find_first_or_last(func, f, args)
  1760.     FL_OBJECT *(*func)(FL_FORM *, int, float, float);
  1761.     formobject *f;
  1762.     object *args;
  1763. {
  1764.     int type;
  1765.     float mx, my;
  1766.     FL_OBJECT *generic;
  1767.     genericobject *g;
  1768.     
  1769.     if (!getargs(args, "(iff)", &type, &mx, &my)) return NULL;
  1770.  
  1771.     generic = (*func) (f-> ob_form, type, mx, my);
  1772.  
  1773.     if (generic == NULL)
  1774.     {
  1775.         INCREF(None);
  1776.         return None;
  1777.     }
  1778.  
  1779.     g = findgeneric(generic);
  1780.     if (g == NULL) {
  1781.         err_setstr(RuntimeError,
  1782.                "forms_find_{first|last} returns unknown object");
  1783.         return NULL;
  1784.     }
  1785.     INCREF(g);
  1786.     return (object *) g;
  1787. }
  1788.  
  1789. static object *
  1790. form_find_first(f, args)
  1791.     formobject *f;
  1792.     object *args;
  1793. {
  1794.     return forms_find_first_or_last(fl_find_first, f, args);
  1795. }
  1796.  
  1797. static object *
  1798. form_find_last(f, args)
  1799.     formobject *f;
  1800.     object *args;
  1801. {
  1802.     return forms_find_first_or_last(fl_find_last, f, args);
  1803. }
  1804.  
  1805. static object *
  1806. form_set_object_focus(f, args)
  1807.     formobject *f;
  1808.     object *args;
  1809. {
  1810.     genericobject *g;
  1811.     if (args == NULL || !is_genericobject(args)) {
  1812.         err_badarg();
  1813.         return NULL;
  1814.     }
  1815.     g = (genericobject *)args;
  1816.     fl_set_object_focus(f->ob_form, g->ob_generic);
  1817.     INCREF(None);
  1818.     return None;
  1819. }
  1820.  
  1821. static struct methodlist form_methods[] = {
  1822. /* adm */
  1823.     {"show_form",        (method)form_show_form},
  1824.     {"hide_form",        (method)form_hide_form},
  1825.     {"redraw_form",        (method)form_redraw_form},
  1826.     {"set_form_position",    (method)form_set_form_position},
  1827.     {"set_form_size",    (method)form_set_form_size},
  1828.     {"scale_form",        (method)form_scale_form},
  1829.     {"freeze_form",        (method)form_freeze_form},
  1830.     {"unfreeze_form",    (method)form_unfreeze_form},
  1831.     {"activate_form",    (method)form_activate_form},
  1832.     {"deactivate_form",    (method)form_deactivate_form},
  1833.     {"bgn_group",        (method)form_bgn_group},
  1834.     {"end_group",        (method)form_end_group},
  1835.     {"find_first",        (method)form_find_first},
  1836.     {"find_last",        (method)form_find_last},
  1837.     {"set_object_focus",    (method)form_set_object_focus},
  1838.  
  1839. /* basic objects */
  1840.     {"add_button",        (method)form_add_button},
  1841. /*    {"add_bitmap",        (method)form_add_bitmap}, */
  1842.     {"add_lightbutton",    (method)form_add_lightbutton},
  1843.     {"add_roundbutton",    (method)form_add_roundbutton},
  1844.     {"add_menu",        (method)form_add_menu},
  1845.     {"add_slider",        (method)form_add_slider},
  1846.     {"add_positioner",    (method)form_add_positioner},
  1847.     {"add_valslider",    (method)form_add_valslider},
  1848.     {"add_dial",        (method)form_add_dial},
  1849.     {"add_counter",        (method)form_add_counter},
  1850.     {"add_box",        (method)form_add_box},
  1851.     {"add_clock",        (method)form_add_clock},
  1852.     {"add_choice",        (method)form_add_choice},
  1853.     {"add_browser",        (method)form_add_browser},
  1854.     {"add_input",        (method)form_add_input},
  1855.     {"add_timer",        (method)form_add_timer},
  1856.     {"add_text",        (method)form_add_text},
  1857.     {NULL,            NULL}        /* sentinel */
  1858. };
  1859.  
  1860. static void
  1861. form_dealloc(f)
  1862.     formobject *f;
  1863. {
  1864.     releaseobjects(f->ob_form);
  1865.     if (f->ob_form->visible)
  1866.         fl_hide_form(f->ob_form);
  1867.     fl_free_form(f->ob_form);
  1868.     DEL(f);
  1869. }
  1870.  
  1871. #define OFF(x) offsetof(FL_FORM, x)
  1872.  
  1873. static struct memberlist form_memberlist[] = {
  1874.     {"window",    T_LONG,        OFF(window),    RO},
  1875.     {"w",        T_FLOAT,    OFF(w)},
  1876.     {"h",        T_FLOAT,    OFF(h)},
  1877.     {"x",        T_FLOAT,    OFF(x),        RO},
  1878.     {"y",        T_FLOAT,    OFF(y),        RO},
  1879.     {"deactivated",    T_INT,        OFF(deactivated)},
  1880.     {"visible",    T_INT,        OFF(visible),    RO},
  1881.     {"frozen",    T_INT,        OFF(frozen),    RO},
  1882.     {"doublebuf",    T_INT,        OFF(doublebuf)},
  1883.     {NULL}    /* Sentinel */
  1884. };
  1885.  
  1886. #undef OFF
  1887.  
  1888. static object *
  1889. form_getattr(f, name)
  1890.     formobject *f;
  1891.     char *name;
  1892. {
  1893.     object *meth;
  1894.  
  1895.     meth = findmethod(form_methods, (object *)f, name);
  1896.     if (meth != NULL)
  1897.         return meth;
  1898.     err_clear();
  1899.     return getmember((char *)f->ob_form, form_memberlist, name);
  1900. }
  1901.  
  1902. static int
  1903. form_setattr(f, name, v)
  1904.     formobject *f;
  1905.     char *name;
  1906.     object *v;
  1907. {
  1908.     int ret;
  1909.  
  1910.     if (v == NULL) {
  1911.         err_setstr(TypeError, "can't delete form attributes");
  1912.         return -1;
  1913.     }
  1914.  
  1915.     return setmember((char *)f->ob_form, form_memberlist, name, v);
  1916. }
  1917.  
  1918. static object *
  1919. form_repr(f)
  1920.     formobject *f;
  1921. {
  1922.     char buf[100];
  1923.     sprintf(buf, "<FORMS_form at %lx, window=%ld>",
  1924.         (long)f, f->ob_form->window);
  1925.     return newstringobject(buf);
  1926. }
  1927.  
  1928. static typeobject Formtype = {
  1929.     OB_HEAD_INIT(&Typetype)
  1930.     0,                /*ob_size*/
  1931.     "FORMS_form",            /*tp_name*/
  1932.     sizeof(formobject),        /*tp_size*/
  1933.     0,                /*tp_itemsize*/
  1934.     /* methods */
  1935.     (destructor)form_dealloc,    /*tp_dealloc*/
  1936.     0,                /*tp_print*/
  1937.     (getattrfunc)form_getattr,    /*tp_getattr*/
  1938.     (setattrfunc)form_setattr,    /*tp_setattr*/
  1939.     0,                /*tp_compare*/
  1940.     (reprfunc)form_repr,        /*tp_repr*/
  1941. };
  1942.  
  1943. static object *
  1944. newformobject(form)
  1945.     FL_FORM *form;
  1946. {
  1947.     formobject *f;
  1948.     f = NEWOBJ(formobject, &Formtype);
  1949.     if (f == NULL)
  1950.         return NULL;
  1951.     f->ob_form = form;
  1952.     return (object *)f;
  1953. }
  1954.  
  1955.  
  1956. /* The "fl" module */
  1957.  
  1958. static object *
  1959. forms_make_form(dummy, args)
  1960.     object *dummy;
  1961.     object *args;
  1962. {
  1963.     int type;
  1964.     float w, h;
  1965.     FL_FORM *form;
  1966.     if (!getargs(args, "(iff)", &type, &w, &h))
  1967.         return NULL;
  1968.     form = fl_bgn_form(type, w, h);
  1969.     if (form == NULL) {
  1970.         /* XXX Actually, cannot happen! */
  1971.         err_nomem();
  1972.         return NULL;
  1973.     }
  1974.     fl_end_form();
  1975.     return newformobject(form);
  1976. }
  1977.  
  1978. static object *
  1979. forms_activate_all_forms(f, args)
  1980.     object *f;
  1981.     object *args;
  1982. {
  1983.     fl_activate_all_forms();
  1984.     INCREF(None);
  1985.     return None;
  1986. }
  1987.  
  1988. static object *
  1989. forms_deactivate_all_forms(f, args)
  1990.     object *f;
  1991.     object *args;
  1992. {
  1993.     fl_deactivate_all_forms();
  1994.     INCREF(None);
  1995.     return None;
  1996. }
  1997.  
  1998. static object *my_event_callback = NULL;
  1999.  
  2000. static object *
  2001. forms_set_event_call_back(dummy, args)
  2002.     object *dummy;
  2003.     object *args;
  2004. {
  2005.     if (args == None)
  2006.         args = NULL;
  2007.     my_event_callback = args;
  2008.     XINCREF(args);
  2009.     INCREF(None);
  2010.     return None;
  2011. }
  2012.  
  2013. static object *
  2014. forms_do_or_check_forms(dummy, args, func)
  2015.     object *dummy;
  2016.     object *args;
  2017.     FL_OBJECT *(*func)();
  2018. {
  2019.     FL_OBJECT *generic;
  2020.     genericobject *g;
  2021.     object *arg, *res;
  2022.     
  2023.     if (!getnoarg(args))
  2024.         return NULL;
  2025.  
  2026.     for (;;) {
  2027.         BGN_SAVE
  2028.         generic = (*func)();
  2029.         END_SAVE
  2030.         if (generic == NULL) {
  2031.             INCREF(None);
  2032.             return None;
  2033.         }
  2034.         if (generic == FL_EVENT) {
  2035.             int dev;
  2036.             short val;
  2037.             if (my_event_callback == NULL)
  2038.                 return newintobject(-1L);
  2039.             dev = fl_qread(&val);
  2040.             arg = mkvalue("(ih)", dev, val);
  2041.             if (arg == NULL)
  2042.                 return NULL;
  2043.             res = call_object(my_event_callback, arg);
  2044.             XDECREF(res);
  2045.             DECREF(arg);
  2046.             if (res == NULL)
  2047.                 return NULL; /* Callback raised exception */
  2048.             continue;
  2049.         }
  2050.         g = findgeneric(generic);
  2051.         if (g == NULL) {
  2052.             /* Object not known to us (some dialogs cause this) */
  2053.             continue; /* Ignore it */
  2054.         }
  2055.         if (g->ob_callback == NULL) {
  2056.             INCREF(g);
  2057.             return ((object *) g);
  2058.         }
  2059.         arg = mkvalue("(OO)", (object *)g, g->ob_callback_arg);
  2060.         if (arg == NULL)
  2061.             return NULL;
  2062.         res = call_object(g->ob_callback, arg);
  2063.         XDECREF(res);
  2064.         DECREF(arg);
  2065.         if (res == NULL)
  2066.             return NULL; /* Callback raised exception */
  2067.     }
  2068. }
  2069.  
  2070. static object *
  2071. forms_do_forms(dummy, args)
  2072.     object *dummy;
  2073.     object *args;
  2074. {
  2075.     return forms_do_or_check_forms(dummy, args, fl_do_forms);
  2076. }
  2077.  
  2078. static object *
  2079. forms_check_forms(dummy, args)
  2080.     object *dummy;
  2081.     object *args;
  2082. {
  2083.     return forms_do_or_check_forms(dummy, args, fl_check_forms);
  2084. }
  2085.  
  2086. static object *
  2087. forms_do_only_forms(dummy, args)
  2088.     object *dummy;
  2089.     object *args;
  2090. {
  2091.     return forms_do_or_check_forms(dummy, args, fl_do_only_forms);
  2092. }
  2093.  
  2094. static object *
  2095. forms_check_only_forms(dummy, args)
  2096.     object *dummy;
  2097.     object *args;
  2098. {
  2099.     return forms_do_or_check_forms(dummy, args, fl_check_only_forms);
  2100. }
  2101.  
  2102. #ifdef UNUSED
  2103. static object *
  2104. fl_call(func, args)
  2105.     object *args;
  2106.     void (*func)();
  2107. {
  2108.     if (!getnoarg(args))
  2109.         return NULL;
  2110.     (*func)();
  2111.     INCREF(None);
  2112.     return None;
  2113. }
  2114. #endif
  2115.  
  2116. static object *
  2117. forms_set_graphics_mode(dummy, args)
  2118.     object *dummy;
  2119.     object *args;
  2120. {
  2121.     int rgbmode, doublebuf;
  2122.  
  2123.     if (!getargs(args, "(ii)", &rgbmode, &doublebuf))
  2124.         return NULL;
  2125.     fl_set_graphics_mode(rgbmode,doublebuf);
  2126.     INCREF(None);
  2127.     return None;
  2128. }
  2129.  
  2130. static object *
  2131. forms_get_rgbmode(dummy, args)
  2132.     object *dummy;
  2133.     object *args;
  2134. {
  2135.     extern int fl_rgbmode;
  2136.  
  2137.     if (args != NULL) {
  2138.         err_badarg();
  2139.         return NULL;
  2140.     }
  2141.     return newintobject((long)fl_rgbmode);
  2142. }
  2143.  
  2144. static object *
  2145. forms_show_errors(dummy, args)
  2146.     object *dummy;
  2147.     object *args;
  2148. {
  2149.     int show;
  2150.     if (!getargs(args, "i", &show))
  2151.         return NULL;
  2152.     fl_show_errors(show);
  2153.     INCREF(None);
  2154.     return None;
  2155. }
  2156.  
  2157. static object *
  2158. forms_set_font_name(dummy, args)
  2159.     object *dummy;
  2160.     object *args;
  2161. {
  2162.     int numb;
  2163.     char *name;
  2164.     if (!getargs(args, "(is)", &numb, &name))
  2165.         return NULL;
  2166.     fl_set_font_name(numb, name);
  2167.     INCREF(None);
  2168.     return None;
  2169. }
  2170.  
  2171.  
  2172. static object *
  2173. forms_qdevice(self, args)
  2174.     object *self;
  2175.     object *args;
  2176. {
  2177.     short arg1;
  2178.     if (!getargs(args, "h", &arg1))
  2179.         return NULL;
  2180.     fl_qdevice(arg1);
  2181.     INCREF(None);
  2182.     return None;
  2183. }
  2184.  
  2185. static object *
  2186. forms_unqdevice(self, args)
  2187.     object *self;
  2188.     object *args;
  2189. {
  2190.     short arg1;
  2191.     if (!getargs(args, "h", &arg1))
  2192.         return NULL;
  2193.     fl_unqdevice(arg1);
  2194.     INCREF(None);
  2195.     return None;
  2196. }
  2197.  
  2198. static object *
  2199. forms_isqueued(self, args)
  2200.     object *self;
  2201.     object *args;
  2202. {
  2203.     long retval;
  2204.     short arg1;
  2205.     if (!getargs(args, "h", &arg1))
  2206.         return NULL;
  2207.     retval = fl_isqueued(arg1);
  2208.  
  2209.     return newintobject(retval);
  2210. }
  2211.  
  2212. static object *
  2213. forms_qtest(self, args)
  2214.     object *self;
  2215.     object *args;
  2216. {
  2217.     long retval;
  2218.     retval = fl_qtest();
  2219.     return newintobject(retval);
  2220. }
  2221.  
  2222.  
  2223. static object *
  2224. forms_qread(self, args)
  2225.     object *self;
  2226.     object *args;
  2227. {
  2228.     int dev;
  2229.     short val;
  2230.     BGN_SAVE
  2231.     dev = fl_qread(&val);
  2232.     END_SAVE
  2233.     return mkvalue("(ih)", dev, val);
  2234. }
  2235.  
  2236. static object *
  2237. forms_qreset(self, args)
  2238.     object *self;
  2239.     object *args;
  2240. {
  2241.     if (!getnoarg(args)) return NULL;
  2242.  
  2243.     fl_qreset();
  2244.     INCREF(None);
  2245.     return None;
  2246. }
  2247.  
  2248. static object *
  2249. forms_qenter(self, args)
  2250.     object *self;
  2251.     object *args;
  2252. {
  2253.     short arg1, arg2;
  2254.     if (!getargs(args, "(hh)", &arg1, &arg2))
  2255.         return NULL;
  2256.     fl_qenter(arg1, arg2);
  2257.     INCREF(None);
  2258.     return None;
  2259. }
  2260.  
  2261. static object *
  2262. forms_color(self, args)
  2263.     object *self;
  2264.     object *args;
  2265. {
  2266.     int arg;
  2267.  
  2268.     if (!getintarg(args, &arg)) return NULL;
  2269.  
  2270.     fl_color((short) arg);
  2271.  
  2272.     INCREF(None);
  2273.     return None;
  2274. }
  2275.  
  2276. static object *
  2277. forms_mapcolor(self, args)
  2278.     object *self;
  2279.     object *args;
  2280. {
  2281.     int arg0, arg1, arg2, arg3;
  2282.  
  2283.     if (!getargs(args, "(iiii)", &arg0, &arg1, &arg2, &arg3))
  2284.         return NULL;
  2285.  
  2286.     fl_mapcolor(arg0, (short) arg1, (short) arg2, (short) arg3);
  2287.  
  2288.     INCREF(None);
  2289.     return None;
  2290. }
  2291.  
  2292. static object *
  2293. forms_getmcolor(self, args)
  2294.     object *self;
  2295.     object *args;
  2296. {
  2297.     int arg;
  2298.     short r, g, b;
  2299.  
  2300.     if (!getintarg(args, &arg)) return NULL;
  2301.  
  2302.     fl_getmcolor(arg, &r, &g, &b);
  2303.  
  2304.     return mkvalue("(hhh)", r, g, b);
  2305. }
  2306.  
  2307. static object *
  2308. forms_get_mouse(self, args)
  2309.     object *self;
  2310.     object *args;
  2311. {
  2312.     float x, y;
  2313.  
  2314.     if (!getnoarg(args)) return NULL;
  2315.     
  2316.     fl_get_mouse(&x, &y);
  2317.  
  2318.     return mkvalue("(ff)", x, y);
  2319. }
  2320.  
  2321. static object *
  2322. forms_tie(self, args)
  2323.     object *self;
  2324.     object *args;
  2325. {
  2326.     short arg1, arg2, arg3;
  2327.     if (!getargs(args, "(hhh)", &arg1, &arg2, &arg3))
  2328.         return NULL;
  2329.     fl_tie(arg1, arg2, arg3);
  2330.     INCREF(None);
  2331.     return None;
  2332. }
  2333.  
  2334. static object *
  2335. forms_show_message(f, args)
  2336.     object *f;
  2337.     object *args;
  2338. {
  2339.     char *a, *b, *c;
  2340.  
  2341.     if (!getargs(args, "(sss)", &a, &b, &c)) return NULL;
  2342.  
  2343.     BGN_SAVE
  2344.     fl_show_message(a, b, c);
  2345.     END_SAVE
  2346.  
  2347.     INCREF(None);
  2348.     return None;
  2349. }
  2350.  
  2351. static object *
  2352. forms_show_choice(f, args)
  2353.     object *f;
  2354.     object *args;
  2355. {
  2356.     char *m1, *m2, *m3, *b1, *b2, *b3;
  2357.     int nb;
  2358.     char *format;
  2359.     long rv;
  2360.  
  2361.     if (args == NULL || !is_tupleobject(args)) {
  2362.         err_badarg();
  2363.         return NULL;
  2364.     }
  2365.     nb = gettuplesize(args) - 3;
  2366.     if (nb <= 0) {
  2367.         err_setstr(TypeError, "need at least one button label");
  2368.         return NULL;
  2369.     }
  2370.     if (is_intobject(gettupleitem(args, 3))) {
  2371.         err_setstr(TypeError,
  2372.                "'number-of-buttons' argument not needed");
  2373.         return NULL;
  2374.     }
  2375.     switch (nb) {
  2376.     case 1: format = "(ssss)"; break;
  2377.     case 2: format = "(sssss)"; break;
  2378.     case 3: format = "(ssssss)"; break;
  2379.     default:
  2380.         err_setstr(TypeError, "too many button labels");
  2381.         return NULL;
  2382.     }
  2383.  
  2384.     if (!getargs(args, format, &m1, &m2, &m3, &b1, &b2, &b3))
  2385.         return NULL;
  2386.  
  2387.     BGN_SAVE
  2388.     rv = fl_show_choice(m1, m2, m3, nb, b1, b2, b3);
  2389.     END_SAVE
  2390.     return newintobject(rv);
  2391. }
  2392.  
  2393. static object *
  2394. forms_show_question(f, args)
  2395.     object *f;
  2396.     object *args;
  2397. {
  2398.     int ret;
  2399.     char *a, *b, *c;
  2400.  
  2401.     if (!getargs(args, "(sss)", &a, &b, &c)) return NULL;
  2402.  
  2403.     BGN_SAVE
  2404.     ret = fl_show_question(a, b, c);
  2405.     END_SAVE
  2406.  
  2407.     return newintobject((long) ret);
  2408. }
  2409.  
  2410. static object *
  2411. forms_show_input(f, args)
  2412.     object *f;
  2413.     object *args;
  2414. {
  2415.     char *str;
  2416.     char *a, *b;
  2417.  
  2418.     if (!getargs(args, "(ss)", &a, &b)) return NULL;
  2419.  
  2420.     BGN_SAVE
  2421.     str = fl_show_input(a, b);
  2422.     END_SAVE
  2423.  
  2424.     if (str == NULL) {
  2425.         INCREF(None);
  2426.         return None;
  2427.     }
  2428.     return newstringobject(str);
  2429. }
  2430.  
  2431. static object *
  2432. forms_file_selector(f, args)
  2433.     object *f;
  2434.     object *args;
  2435. {
  2436.     char *str;
  2437.     char *a, *b, *c, *d;
  2438.  
  2439.     if (!getargs(args, "(ssss)", &a, &b, &c, &d)) return NULL;
  2440.  
  2441.     BGN_SAVE
  2442.     str = fl_show_file_selector(a, b, c, d);
  2443.     END_SAVE
  2444.  
  2445.     if (str == NULL) {
  2446.         INCREF(None);
  2447.         return None;
  2448.     }
  2449.     return newstringobject(str);
  2450. }
  2451.  
  2452.  
  2453. static object *
  2454. forms_file_selector_func(args, func)
  2455.     object *args;
  2456.     char *(*func)();
  2457. {
  2458.     char *str;
  2459.  
  2460.     str = (*func) ();
  2461.  
  2462.     if (str == NULL) {
  2463.         INCREF(None);
  2464.         return None;
  2465.     }
  2466.     return newstringobject(str);
  2467. }
  2468.  
  2469. static object *
  2470. forms_get_directory(f, args)
  2471.     object *f;
  2472.     object *args;
  2473. {
  2474.     return forms_file_selector_func(args, fl_get_directory);
  2475. }
  2476.  
  2477. static object *
  2478. forms_get_pattern(f, args)
  2479.     object *f;
  2480.     object *args;
  2481. {
  2482.     return forms_file_selector_func(args, fl_get_pattern);
  2483. }
  2484.  
  2485. static object *
  2486. forms_get_filename(f, args)
  2487.     object *f;
  2488.     object *args;
  2489. {
  2490.     return forms_file_selector_func(args, fl_get_filename);
  2491. }
  2492.  
  2493. static struct methodlist forms_methods[] = {
  2494. /* adm */
  2495.     {"make_form",        forms_make_form},
  2496.     {"activate_all_forms",    forms_activate_all_forms},
  2497.     {"deactivate_all_forms",forms_deactivate_all_forms},
  2498. /* gl support wrappers */
  2499.     {"qdevice",        forms_qdevice},
  2500.     {"unqdevice",        forms_unqdevice},
  2501.     {"isqueued",        forms_isqueued},
  2502.     {"qtest",        forms_qtest},
  2503.     {"qread",        forms_qread},
  2504. /*    {"blkqread",        forms_blkqread}, */
  2505.     {"qreset",        forms_qreset},
  2506.     {"qenter",        forms_qenter},
  2507.     {"get_mouse",        forms_get_mouse},
  2508.     {"tie",            forms_tie},
  2509. /*    {"new_events",        forms_new_events}, */
  2510.     {"color",        forms_color},
  2511.     {"mapcolor",        forms_mapcolor},
  2512.     {"getmcolor",        forms_getmcolor},
  2513. /* interaction */
  2514.     {"do_forms",        forms_do_forms},
  2515.     {"do_only_forms",    forms_do_only_forms},
  2516.     {"check_forms",        forms_check_forms},
  2517.     {"check_only_forms",    forms_check_only_forms},
  2518.     {"set_event_call_back",    forms_set_event_call_back},
  2519. /* goodies */
  2520.     {"show_message",    forms_show_message},
  2521.     {"show_question",    forms_show_question},
  2522.     {"show_choice",        forms_show_choice},
  2523.     {"show_input",        forms_show_input},
  2524.     {"show_file_selector",    forms_file_selector},
  2525.     {"file_selector",    forms_file_selector}, /* BW compat */
  2526.     {"get_directory",    forms_get_directory},
  2527.     {"get_pattern",        forms_get_pattern},
  2528.     {"get_filename",    forms_get_filename},
  2529.     {"set_graphics_mode",    forms_set_graphics_mode},
  2530.     {"get_rgbmode",        forms_get_rgbmode},
  2531.     {"show_errors",        forms_show_errors},
  2532.     {"set_font_name",    forms_set_font_name},
  2533.     {NULL,            NULL}        /* sentinel */
  2534. };
  2535.  
  2536. void
  2537. initfl()
  2538. {
  2539.     initmodule("fl", forms_methods);
  2540.     foreground();
  2541.     fl_init();
  2542. }
  2543.